package net.sureon.biz;

import java.util.ArrayList;
import java.util.List;

import net.sureon.common.cache.InCompanyCacheProvider;
import net.sureon.common.cache.LRUCache;
import net.sureon.common.exception.SureonException;
import net.sureon.dao.Group;
import net.sureon.dao.GroupDAO;

public class GroupMgrImpl implements GroupMgr {

	private GroupDAO groupDAO;
	private CompanyMgr companyMgr;

	public GroupMgrImpl() {
	}

	/**
	 * @return the groupDAO
	 */
	public GroupDAO getGroupDAO() {
		return groupDAO;
	}

	/**
	 * @param groupDAO
	 *            the groupDAO to set
	 */
	public void setGroupDAO(GroupDAO groupDAO) {
		this.groupDAO = groupDAO;
	}

	/**
	 * @return the companyMgr
	 */
	public CompanyMgr getCompanyMgr() {
		return companyMgr;
	}

	/**
	 * @param companyMgr
	 *            the companyMgr to set
	 */
	public void setCompanyMgr(CompanyMgr companyMgr) {
		this.companyMgr = companyMgr;
	}

	public GroupBO getGroup(long companyID, long groupID)
			throws SureonException {
		LRUCache cache = InCompanyCacheProvider.getInstance().getGroupCache(
				companyID);
		Object o = cache.get(groupID);
		if (o == null) {
			o = new GroupBO(getGroupDAO().getGroup(companyID, groupID));
			List<Group> childGroups = groupDAO.getChildGroups(companyID,
					groupID);
			for (Group childGroup : childGroups) {
				((GroupBO) o).addChildGroup(getGroup(companyID, childGroup
						.getGroupID()));
			}
			cache.put(groupID, o);
		}
		return (GroupBO) o;
	}

	// private static final String CK_companyGroups = "CK_companyGroups";
	public List<GroupBO> getGroupByCompanyID(long companyID)
			throws SureonException {
		LRUCache cache = InCompanyCacheProvider.getInstance().getGroupCache(
				companyID);
		// Object companyGroups = cache.get(CK_companyGroups);
		// if(companyGroups != null){
		// return (List<GroupBO>) companyGroups;
		// }
		List<Group> groups = getGroupDAO().getGroupByCompanyID(companyID);
		List<GroupBO> groupBOs = new ArrayList<GroupBO>();
		List<Group> childGroups;
		for (Group group : groups) {
			GroupBO theBO = (GroupBO) cache.get(group.getGroupID());
			if (theBO == null) {
				theBO = new GroupBO(group);
				childGroups = groupDAO.getChildGroups(companyID, group
						.getGroupID());
				for (Group childGroup : childGroups) {
					theBO.addChildGroup(getGroup(companyID, childGroup
							.getGroupID()));
				}
				cache.put(group.getGroupID(), theBO);
			}
			groupBOs.add(theBO);
		}
		// cache.put(CK_companyGroups, groupBOs);
		return groupBOs;
	}

	public long insertGroup(GroupBO group) throws SureonException {
		Long groupID = getGroupDAO().insertGroup(group.getGroupVO());
		group.getGroupVO().setGroupID(groupID);
		LRUCache cache = InCompanyCacheProvider.getInstance().getGroupCache(
				group.getGroupVO().getCompanyID());
		cache.clean();
		return groupID;
	}

	public int updateGroup(GroupBO group) throws SureonException {
		int affectedRows = getGroupDAO().updateGroup(group.getGroupVO());
		LRUCache cache = InCompanyCacheProvider.getInstance().getGroupCache(
				group.getGroupVO().getCompanyID());
		cache.clean();
		return affectedRows;
	}

	public GroupBO getDirectParentGroup(long companyID, long groupID,
			long theUser) throws SureonException {
		if (groupID > 0) {
			GroupBO group = getGroup(companyID, groupID);
			if (group.getGroupVO().getGroupManager() >= 0
					&& group.getGroupVO().getGroupManager() != theUser) {
				return group;
			} else {
				return getDirectParentGroup(companyID, group.getGroupVO()
						.getParentGroup(), theUser);
			}
		}
		return null;
	}

	public GroupBO getCompanyTopGroup(long companyID) throws SureonException {
		CompanyBO company = companyMgr.getCompany(companyID);
		long topGroupID = 0;
		if (company.getTopGroupID() > 0) {
			topGroupID = company.getTopGroupID();
		} else {
			topGroupID = groupDAO.getCompanyTopGroupID(companyID);
			company.setTopGroupID(topGroupID);
		}
		return getGroup(companyID, company.getTopGroupID());
	}

	public int deleteNullGroup(long companyID, long groupID) throws SureonException{
		int result = groupDAO.deleteNullGroup(companyID, groupID);
		LRUCache cache = InCompanyCacheProvider.getInstance().getGroupCache(
				companyID);
		cache.clean();
		return result;
		
	}

	public List<GroupBO> getGroupByName(long companyID, String groupName) {
		List<Group> vos = groupDAO.getGroupByName(companyID, groupName);
		List<GroupBO> groups = new ArrayList<GroupBO>();
		if (vos == null) {
			return null;
		} else {
			for(Group vo : vos) {
				groups.add(new GroupBO(vo));
			}
			return groups;
		}
	}

	public long getManagedGroup(long companyID, long userID)
			throws SureonException {
		return groupDAO.getManagedGroup(companyID, userID);
	}
}
